package ee.ut.maxorato_macobo.oop.mudclient.network;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import ee.ut.maxorato_macobo.oop.mudclient.ClientMain;

public class ClientIoManager {
	private static Channel ioChannel = null;
	private static ClientBootstrap nettyBootstrap = null;
	private static String lastHostName = "";
	private static int lastPort = 0;
	private static boolean isConnected = false;
	
	public static void initNetty() {
		nettyBootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
		nettyBootstrap.setPipelineFactory(new ClientPipelineFactory());
	}
	
	public static void connectNetty(String hostName, int port) {
		isConnected = false;
		
        ChannelFuture future = nettyBootstrap.connect(new InetSocketAddress(hostName, port));
        
        lastHostName = hostName;
        lastPort = port;

        Channel channel = future.awaitUninterruptibly().getChannel();
        
        if (!future.isSuccess()) {
            //future.getCause().printStackTrace();
        	gotInput("\033[1;31mUnable to connect to " + lastHostName + ":" + lastPort + ".\033[0m\n");
            ClientMain.setConnection(false);
        	return;
        }
        
        isConnected = true;
        
        ClientIoManager.setChannel(channel);
        ClientMain.setConnection(true);
        gotInput("\033[1;31mConnected to " + lastHostName + ":" + lastPort + ".\033[0m\n");
	}
	
	public static void disconnectNetty() {
		if (ioChannel != null)
			ioChannel.disconnect();
		ioChannel = null;
	}
	
	public static void gotDisconnected() {
		isConnected = false;
		ClientMain.setConnection(false);
		gotInput("\033[1;31mDisconnected from " + lastHostName + ":" + lastPort + ".\033[0m\n");
		
	}
	
	public static void setChannel(Channel newIoChannel) {
		ioChannel = newIoChannel;
	}
	
	public static boolean getIsConnected() {
		return isConnected;
	}
	
	public static void gotInput(String inputText) {
		System.out.println(inputText);
		
		ClientMain.getMainWindow().addInputToView(inputText);
	}
	
	public static void sendOutput(String outputText) {
		if(outputText.charAt(0) == '#') {
			String[] tokens = outputText.replaceAll("\n", " ").split(" ");
			
			if(tokens[0].equals("#conn")) {
				if(tokens.length == 3) {
					int portNumber = 0;
					
					try { portNumber = Integer.parseInt(tokens[2]); } catch(Exception e) { }
					
					if(isConnected && ioChannel != null) {
						ioChannel.close();
					}
					
					connectNetty(tokens[1], portNumber);
				}
				else {
					gotInput("\033[1;31mInvalid connect parameters.\033[0m\n");
				}
			}
			else if(tokens[0].equals("#disconn")) {
				if(isConnected && ioChannel != null) {
					ioChannel.close();
				}
				else {
					gotInput("\033[1;31mYou are not connected.\033[0m\n");
				}
			}
			else {
				gotInput("\033[1;31mUnknown command.\033[0m\n");
			}
		}
		else if(isConnected && ioChannel != null) {
			ioChannel.write(outputText);
		}
	}
}
